import 'dart:async';

import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:flutter/cupertino.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:wallet_utils/location/permissions_options.dart';

import '../log_util.dart';
import '../permissions_utils.dart';



bool _isFirstRequestLocation = true;

class LocationUtil {
  LocationUtil.internal();

  static final LocationUtil locationUtil = LocationUtil.internal();

  static bool isOpenLocationSetting = false;

  Map<String, Object>? _locationResult;

  StreamSubscription<Map<String, Object>>? locationListener;

   AMapFlutterLocation locationPlugin = AMapFlutterLocation();

  final List<ValueChanged<Map<String, Object>>> _resultList = [];
  final List<VoidCallback> _errorList = [];

  factory LocationUtil() {
    return locationUtil;
  }

  ///初始化
  void init() {
    // AMapFlutterLocation.setApiKey('d1037b5fec7bce515452e2d2569287fc', '');
    // AMapFlutterLocation.setApiKey('eb8b3cfc1464646880c453ff852f5f7c', '');
    AMapFlutterLocation.setApiKey('1347008028ff1741d1d1565af8f2f8d0', '34fe9897bd292d236a67fb46b963aa0f');


    AMapFlutterLocation.updatePrivacyShow(true, true);
    AMapFlutterLocation.updatePrivacyAgree(true);

    ///注册定位结果监听
    locationListener = locationPlugin.onLocationChanged().listen((Map<String, Object> result) {
      LogUtils.d("定位了");
      /// 如果有定位结果，回调onResult
      if (result != null &&
          ((result["city"] as String?)?.isNotEmpty ?? false) &&
          ((result["cityCode"] as String?)?.isNotEmpty ?? false)) {
        _locationResult = result;
        for (ValueChanged<Map<String, Object>> valueChangeResult in _resultList) {
          valueChangeResult.call(result);
        }
      /// 否则回调onError
      } else {
        for (VoidCallback voidCallback in _errorList) {
          voidCallback.call();
        }
      }
      _resultList.clear();
      _errorList.clear();
    });
  }

  AMapFlutterLocation getLocationPlugin() {
    return locationPlugin;
  }

  /// 动态申请定位权限
  Future<bool> request(
      {bool isShowRejectDialog = false,
      required ValueChanged<Map<String, Object>> onResult,
      VoidCallback? onError,
      bool isResetLocation = false}) async {
    /// 检查定位服务是否开启
    bool serviceEnabled = await Geolocator.isLocationServiceEnabled();

    /// 只在打开app后的第一次定位去弹出引导弹框
    if (!serviceEnabled) {
      if (_isFirstRequestLocation) {
        _isFirstRequestLocation = false;
        showOpenGpsDialog();
      }
      return false;
    }
    // 申请权限
    bool isGranted =
        await PermissionsUtils.request(PermissionType.location, Get.context, isShowRejectDialog: isShowRejectDialog);
    if (!isGranted) return isGranted;
    if (isResetLocation) {
      _request(onResult: onResult, onError: onError);
      return isGranted;
    }
    if (_locationResult != null) {
      onResult.call(_locationResult!);
      return isGranted;
    }
    _request(onResult: onResult, onError: onError);
    return isGranted;
  }

  void _request({
    required ValueChanged<Map<String, Object>> onResult,
    VoidCallback? onError,
  }) {
    _startLocation();
    _resultList.add(onResult);
    if (onError != null) _errorList.add(onError);
  }

  /// onPermissionGranted 仅限 权限请求成功后的回调
  Future<void> toSettingPage({required VoidCallback onPermissionGranted}) async {
    bool serviceEnabled = await Geolocator.isLocationServiceEnabled();

    /// gps未开启
    if (!serviceEnabled) {
      /// 如果定位服务未开启，但是app位置权限是同意的情况，我们认为是打开了设置页，从设置回来要刷新位置状态
      PermissionStatus? status = await Permission.location.status;
      if (status.isGranted) {
        isOpenLocationSetting = true;
      }
      Geolocator.openLocationSettings();
      return;
    }

    /// 权限未开启
    bool isGranted = await PermissionsUtils.request(PermissionType.location, Get.context, isShowRejectDialog: false);
    if (!isGranted) {
      isOpenLocationSetting = true;
      Future.delayed(const Duration(milliseconds: 300), () {
        PermissionsUtils.openSetting();
      });
      return;
    }
    onPermissionGranted.call();
  }

  void showOpenGpsDialog() {
    if (Get.context == null) return;
    defaultShowPermisionsDialogBuilder.call(Get.context!, hint: "您的手机定位服务未开启，无法定位您的位置，是否开启？", rightBtnText: "开启",
        onClick: () async {
      Get.back();
      Geolocator.openLocationSettings();
    });
  }

  Future<bool> isLocationPermissionGranted() async {
    return await Permission.location.status.isGranted;
  }

  ///设置定位参数
  void _setLocationOption() {
    AMapLocationOption locationOption = AMapLocationOption();

    ///是否单次定位
    locationOption.onceLocation = true;

    ///是否需要返回逆地理信息
    locationOption.needAddress = true;

    ///逆地理信息的语言类型
    locationOption.geoLanguage = GeoLanguage.DEFAULT;

    locationOption.desiredLocationAccuracyAuthorizationMode = AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;

    locationOption.fullAccuracyPurposeKey = "AMapLocationScene";

    ///设置Android端连续定位的定位间隔
    locationOption.locationInterval = 2000;

    ///设置Android端的定位模式<br>
    ///可选值：<br>
    ///<li>[AMapLocationMode.Battery_Saving]</li>
    ///<li>[AMapLocationMode.Device_Sensors]</li>
    ///<li>[AMapLocationMode.Hight_Accuracy]</li>
    locationOption.locationMode = AMapLocationMode.Hight_Accuracy;

    ///设置iOS端的定位最小更新距离<br>
    locationOption.distanceFilter = -1;

    ///设置iOS端期望的定位精度
    /// 可选值：<br>
    /// <li>[DesiredAccuracy.Best] 最高精度</li>
    /// <li>[DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度 </li>
    /// <li>[DesiredAccuracy.NearestTenMeters] 10米 </li>
    /// <li>[DesiredAccuracy.Kilometer] 1000米</li>
    /// <li>[DesiredAccuracy.ThreeKilometers] 3000米</li>
    locationOption.desiredAccuracy = DesiredAccuracy.Best;

    ///设置iOS端是否允许系统暂停定位
    locationOption.pausesLocationUpdatesAutomatically = false;

    ///将定位参数设置给定位插件
    locationPlugin.setLocationOption(locationOption);
  }

  ///开始定位
  void _startLocation() {
    ///开始定位之前设置定位参数
    _setLocationOption();

    locationPlugin.startLocation();
  }

  ///停止定位
  void stopLocation() {
    locationPlugin.stopLocation();
  }

  ///销毁定位
  void destroyLocation() {
    locationPlugin.destroy();
  }

  void cancel() {
    if (null != locationListener) {
      locationListener?.cancel(); // 停止定位
    }
  }
}
